import { expect } from '@jest/globals';
import fsExtra from 'fs-extra';
import JSON5 from 'json5';
import path from 'path';

import { initExecuteCommand, runHvigorAsync } from '../../common/common';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  IsEnable,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType,
  SignType
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOption } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API10,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility
  },
};

const taskConfig: TestTaskOption = {
  caseLevel: CaseLevel.L1,
  sign: SignType.NoSign,
  ohpmInstall: IsEnable.DisAble,
};

const testFun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();
  const commandModule = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHap',
    module: 'entry'
  });
  const commandProject = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHap'
  });
  const commandClean = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'clean'
  });

  // 添加targets
  const entryPath = project.getModule('entry').moduleRootPath();
  const jsonData = await fsExtra.readFile(path.resolve(entryPath, 'build-profile.json5'));
  const parse = JSON5.parse(jsonData.toString());
  parse.targets.push({ 'name': 'e2eTest' });

  await fsExtra.writeFile(path.resolve(entryPath, 'build-profile.json5'), JSON5.stringify(parse), 'utf-8');

  // 执行 ./hvigorw assembleHap -m module -p module=entry 构建
  const buildModuleResult = await runHvigorAsync(projectRootPath, commandModule);
  record.addStep('执行/hvigorw assembleHap -m module -p module=entry 构建', buildModuleResult);
  expect(buildModuleResult.stdout).toContain('Finished :entry:e2eTest@PackageHap');
  expect(buildModuleResult.stdout).toContain('Finished :entry:default@SignHap');
  expect(buildModuleResult.stdout).toContain('BUILD SUCCESSFUL');

  // 判断构建的产物是否包含多个hap包
  const existDefault = await fsExtra.pathExists(
    path.resolve(project.getModule('entry').moduleRootPath(),
      'build/default/outputs/default/entry-default-unsigned.hap'));
  const existE2ETest = await fsExtra.pathExists(
    path.resolve(project.getModule('entry').moduleRootPath(),
      'build/default/outputs/e2eTest/entry-e2eTest-unsigned.hap'));
  expect(existDefault).toBe(true);
  expect(existE2ETest).toBe(true);

  // 清除构建产物
  await runHvigorAsync(projectRootPath, commandClean);

  // 执行 ./hvigorw assembleHap 构建
  const buildProjectResult = await runHvigorAsync(projectRootPath, commandProject);
  record.addStep('执行 ./hvigorw assembleHap 构建', buildProjectResult);
  expect(buildProjectResult.stdout).toContain('Finished :entry:e2eTest@PackageHap');
  expect(buildProjectResult.stdout).toContain('Finished :entry:default@SignHap');
  expect(buildProjectResult.stdout).toContain('BUILD SUCCESSFUL');

  // 判断构建的产物是否包含多个hap包
  const existDefault1 = await fsExtra.pathExists(
    path.resolve(project.getModule('entry').moduleRootPath(),
      'build/default/outputs/default/entry-default-unsigned.hap'));
  const existE2ETest1 = await fsExtra.pathExists(
    path.resolve(project.getModule('entry').moduleRootPath(),
      'build/default/outputs/e2eTest/entry-e2eTest-unsigned.hap'));
  expect(existDefault1).toBe(true);
  expect(existE2ETest1).toBe(true);

};

TestCaseBuilder.builder()
  .caseName('OPEN_LAB_AIDE_ZOS_module_build_multiHap_HOS_API10_STAGE_01')
  .description('单模块多targets，命令行未指定targets')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(taskConfig)
  .testFun(testFun)
  .load();
